home *** CD-ROM | disk | FTP | other *** search
- PAGE ,132
- TITLE CD-ROM Error Corect routine for IBM PC
- NAME ECC
- ; ***************************************************************************
- ; * *
- ; * Hitachi CDR-3600/1600S C D - R O M Device Driver *
- ; * Copyright reserved by Hitachi, Ltd. *
- ; * *
- ; * ECC version MOD21. *
- ; * *
- ; * This is module corrects errors the drive was not able to. *
- ; * *
- ; * *
- ; * History: *
- ; * *
- ; * Created. *
- ; * Oct. 07,1985 -by- H. ONO *
- ; * Modified. *
- ; * Mar. 30,1989 -by- T.ENOKI *
- ; * Modified (v2.20) *
- ; * 10/1/90 -by- JohnYG *
- ; * Final Release (v2.20) *
- ; * *
- ; ***************************************************************************
- ;------------------------------------------------------
- ; N E A R T Y P E
- ;------------------------------------------------------
- _TEXT SEGMENT BYTE PUBLIC 'CODE'
- ASSUME CS:_TEXT,ES:_TEXT,DS:_TEXT
- EXTRN BUF:BYTE
- PUBLIC ECC
- ECC PROC NEAR
- JMP short START_ECC
- NOP
- INIT_MES DB " ECCMOD21 "
- ;----------------------------------------------------------------------
- ; W O R K A R E A
- ;---------------------------------------------------------------------
- ; ECC DECODER
- ;
- PQ_KAISU DB 4 ;P,Q PARITY HOSEI LOOP KAISU
- P_OK DW 0FFFFH ;P PARITY ERROR FLAG
- Q_OK DW 0FFFFH ;Q PARITY ERROR FLAG
- P_NO DW 0 ;P PARITY CHECK NO
- Q_NO DW 0 ;Q PARITY CHECK NO
- S0 DB 0 ;S0 SYNDOROME
- S1 DB 0 ;S1 SYNDOROME
- E_OK DB 0 ;EVEN OK FLAG
- O_OK DB 0 ;ODD OK FLAG
- W_DATA_AD_OFF DW 0 ;DATA BLOCK START ADDRESS
- ;;;;W_DATA_AD_SEG DW 0 ; " " " "
- SI_SAVE DW 0 ;Q0 CODE START ADDRESS
- TMAT_FLAG DB 0 ;0 -- NO INITIALIZE 1 -- ALREADY DONE
- ;----------------------------------------------------------------------
- ; E C C D E C O D E R O U T I N E
- ;----------------------------------------------------------------------
- START_ECC:
- CLD
- PUSH DS ;SAVE -- EDIT 4/10/'86
- PUSH ES
- PUSH CS
- POP DS ;DS <- CS
- PUSH CS
- POP ES ;ES <- CS
- CMP TMAT_FLAG,0
- JNE ECC_ST_1
- CALL T_MAT_MAKE ;T_MATRIX SARCH TABLE MAKE
- MOV TMAT_FLAG,1
- ECC_ST_1:
- MOV W_DATA_AD_OFF,OFFSET BUF ;EVEN AREA START ADDRESS SET
- ;;; MOV W_DATA_AD_SEG,SEG BUF ;
- ;;; MOV ES,W_DATA_AD_SEG ;
- CALL HALF ;EVEN REGION HOSEI
- JC ECC_END ;
- INC W_DATA_AD_OFF ;ODD AREA START ADDRESS SET
- CALL HALF ;ODD REGION HOSEI
- ECC_END:
- POP ES
- POP DS ;RESTORE-- EDIT 4/10/'86
- RET
- ;----------------------------------------------------------------------
- ; R O C A L P R O C E D U R E
- ;----------------------------------------------------------------------
- ROPRO PROC NEAR
- ;----------------------------------------------------------------------
- ; HALF
- ;
- HALF: MOV PQ_KAISU,4 ;P,Q PARITY HOSEI KAISU
- MOV Q_OK,0FFFFH ;Q_OK = 0FFFFH
- HAL_1:
- MOV P_OK,0 ;P_OK = 0
- MOV CX,43 ;LOOP KAISU = 43
- HAL_2:
- PUSH CX
- DEC CX ;P_NO = LOOP COUNT - 1 (42 - 0)
- MOV P_NO,CX ;P_NO SET
- CALL P_ ;P_PARITY HOSEI
- POP CX
- LOOP HAL_2
- TEST P_OK,0FFFFH ;IF P_PARITY HOSEI NG -> Q_PARITY HOSEI
- JNZ HAL_3
- TEST Q_OK,0FFFFH
- JZ OK_END ;P,Q PARITY HOSEI OK -> OK_END
- HAL_3:
- MOV Q_OK,0 ;Q_OK = 0
- MOV CX,26 ;LOOP KAISU = 26
- HAL_4:
- PUSH CX
- DEC CX ;Q_NO = LOOP COUNT - 1 ( 25 - 0 )
- MOV Q_NO,CX ;Q_NO SET
- CALL Q_ ;Q_PARITY HOSEI
- POP CX
- LOOP HAL_4
- TEST Q_OK,0FFFFH
- JNZ HAL_5 ;IF Q_PARITY HOSEI NG -> P_PARITY HOSEI
- TEST P_OK,0FFFFH
- JNZ HAL_5
- OK_END: ;P,Q PARITY HOSEI OK -> CY=0
- CLC
- RET ;CORECTION COMPLETE
- HAL_5:
- DEC PQ_KAISU ;P,Q PARITY HOSEI KAISU END?
- JNZ HAL_1
- STC ;P,Q PARITY HOSEI NG CY=1
- RET
- ;------------------------------------------------------------------
- P_: ;P_PARITY CHECK
- MOV SI,W_DATA_AD_OFF ;SI<- INITIAL ADDRESS
- ADD SI,P_NO
- ADD SI,P_NO ;SI<- SI+2*P_NO
- MOV CX,25 ;LOOP KAISU =25 W(0),--,W(23),P0,P1
- MOV AH,[SI] ;AH <- W(0)
- P_12:
- ROL AH,1 ;1BIT LEFT ROTATE SHIFT
- JNC P_13
- XOR AH,1CH ;AH=T*W(i)
- P_13:
- ADD SI,43*2
- XOR AH,[SI] ;AH=T*W(i) EOR W(i+1) P0,P1
- LOOP P_12
- MOV S1,AH ;S1 SYNDOROME
- ;
- MOV SI,W_DATA_AD_OFF ;SI <- INITIAL ADDRESS
- ADD SI,WORD PTR P_NO
- ADD SI,WORD PTR P_NO ;SI <- SI+2*P_NO
- MOV AH,[SI] ;AH=W(0)
- MOV CX,25 ;LOOP KAISU = 25 W(0),--,W(23),P0,P1
- P_5:
- ADD SI,43*2 ;SI <- SI+43*2
- MOV AL,[SI] ;
- XOR AH,AL ;AH = W(i) EOR W(i+1) P0,P1
- LOOP P_5
- MOV S0,AH ;S0 SYNDOROME
- JNZ P_55 ;IF S1<>0 GOTO HOSEI ROUTINE
- TEST S1,0FFH ;
- JZ RET_0 ;IF S1=0 RETURN
- P_54: ADD WORD PTR P_OK,100H ;P_OK <- P_OK + 100H HOSEI NG
- RET_0: RET ;
- P_55:
- TEST S1,0FFH ;IF S1=0 HOSEI NG ( S0<>0 )
- JZ P_54
- ;
- P_6:
- CALL T_SARCH ;T_MATRIX NO SARCH
- MOV SI,W_DATA_AD_OFF ;SI <- INITIAL ADDRESS SET
- ADD SI,P_NO
- ADD SI,P_NO ;SI<- SI+2*P_NO
- ADD CL,25 ;CL <- CL+25
- JE P_66
- CMP CL,25 ; 0 - 25 -> 26 data
- JA P_54 ;IF CL > 25 HOSEI NG
- P_65: ;HOSEI SURU DATA NO ADDRESS SARCH
- ADD SI,43*2 ;SI <- SI+2*43
- LOOP P_65 ;
- P_66: MOV AL,S0 ;
- XOR [SI],AL ;1 BYTE HOSEI END
- P_ECC_RET:
- INC P_OK ;P_PARITY HOSEI KAISU INCREMENT
- RET
- ;-----------------------------------------------------------------
- Q_: ;Q PARITY CHECK
- CALL Q_NO_ST ;Q PARITY START ADDRESS SET
- MOV CX,42 ;LOOP KAISU = 42 W(0),--,W(42)
- Q_12:
- ROL AH,1 ;1 BIT LEFT ROTATE SHIFT
- JNC Q_14
- XOR AH,1CH ;AH <- T*W(i)
- Q_14:
- ADD SI,44*2 ;NEXT SI ADDRESS SET
- CMP SI,1118*2+OFFSET BUF ;ORIKAESI CHECK
- JB Q_16 ;IF ORIKAESI SI <- SI-2*1118
- SUB SI,1118*2
- Q_16:
- XOR AH,[SI] ;AH = W(i) EOR W(i+1)
- LOOP Q_12
- ROL AH,1
- JNC Q_17
- XOR AH,1CH ;AH <- T*AH
- Q_17:
- MOV SI,W_DATA_AD_OFF ;SI <- INITIAL ADDRESS SET
- ADD SI,Q_NO
- ADD SI,Q_NO ;SI <- SI+2*Q_NO
- ADD SI,1118*2 ;SI <- SI+2*1118
- MOV SI_SAVE,SI ;Q0 CODE START ADDRESS SAVE
- XOR AH,[SI] ;AH=AH EOR Q0
- ROL AH,1
- JNC Q_18 ;AH = T * AH
- XOR AH,1CH
- Q_18:
- ADD SI,26*2 ;SI <- SI+2*26
- XOR AH,[SI] ;AH <- AH EOR Q1
- MOV S1,AH ;S1 SYNDOROME
- CALL Q_NO_ST ;Q_PARITY START ADDRESS SET
- MOV CX,42 ;LOOP KAISU = 42 W(0),--,W(42)
- Q_7:
- ADD SI,44*2 ;NEXT SI ADDRESS SET
- CMP SI,1118*2+OFFSET BUF ;ORIKAESI CHECK O.K.?
- JB Q_8
- SUB SI,1118*2 ;IF ORIKAESI SI <- SI -2*1118
- Q_8:
- XOR AH,[SI] ;AH = W(i) EOR W(i+1)
- LOOP Q_7
- MOV SI,SI_SAVE ;Q0 CODE START ADDRESS SET
- XOR AH,[SI] ;AH <- AH EOR Q0
- ADD SI,26*2
- XOR AH,[SI] ;AH <- AH EOR Q1
- MOV S0,AH ;S0 SYNDOROME
- JNZ Q_55 ;IF S0<>0 GO TO HOSEI ROUTINE
- TEST S1,0FFH
- JZ RET_2 ;IF S1=0 RETURN
- Q_54: ADD WORD PTR Q_OK,100H ;HOSEI NG
- RET_2: RET
- Q_55:
- TEST S1,0FFH ;IF S1=0 HOSEI NG ( S0<>0 )
- JZ Q_54
- ;
- Q_ECC:
- CALL T_SARCH ;T_MATRIX NO SARCH
- MOV SI,W_DATA_AD_OFF ;SI <- INITIAL ADDRESS SET
- ADD CL,44 ;CL <- CL+44
- JE Q_ECC_3 ;CL=0
- CMP CL,44 ;IF CL > 44 HOSEI NG
- JA Q_ECC_NG
- CMP CL,42 ;IF CL = 43,44 Q0,Q1 HOSEI
- JA Q_ECC_5
- Q_ECC_3:
- XOR AH,AH ;AH=0
- PUSH CX
- CALL Q_NO_ST ;Q_PARITY START ADDRESS SET
- POP CX
- OR CL,CL ;CL = 0 ?
- JZ Q_ECC_8 ;IF CL = 0 W(0) HOSEI
- Q_ECC_44:
- ADD SI,44*2 ;SI <- SI+2*44
- CMP SI,1118*2+OFFSET BUF ;ORIKAESI CHECK
- JB Q_ECC_46
- SUB SI,1118*2 ;IF ORIKAESI SI <- SI-2*1118
- Q_ECC_46:
- LOOP Q_ECC_44
- Q_ECC_8: MOV AL,S0
- XOR [SI],AL ;1 BYTE HOSEI END
- Q_ECC_RET:
- INC Q_OK ;Q_PARITY HOSEI KAISU INCREMENT
- RET
- Q_ECC_NG: ADD Q_OK,100H ;Q_PARITY HOSEI NG Q_OK <- Q_OK+100H
- RET
- Q_ECC_5: ;Q0 , Q1 HOSEI
- MOV SI,SI_SAVE ;Q0 CODE START ADDRESS SET
- SUB CL,43 ;CL <- CL-43
- JZ Q_ECC_8 ;IF CL=0 Q0 HOSEI
- ADD SI,26*2 ;SI <- SI+2*26 Q1 HOSEI
- JMP Q_ECC_8
- ;--------------------------------------------------------------------
- T_MAT_MAKE:
- CLD
- MOV DI,OFFSET T_MAT_TBL ;DI <- T_MARIX START ADDRESS SET
- MOV CX,255 ;T**255 = 1 -> T(1)
- XOR BH,BH ;BH=0
- MOV AL,1
- CALL STOS_B
- DEC CX ;LOOP KAISU = 254
- NEXT:
- ROL AL,1
- JNC NEXT_1 ;AL <- T*AL
- XOR AL,1CH
- NEXT_1:
- CALL STOS_B
- LOOP NEXT
- RET
- ;------------------------------------------------------------
- STOS_B:
- MOV DX,255
- SUB DX,CX ;T*(255-CX) -> T(255-CX)
- MOV BL,AL
- MOV [DI+BX],DL
- RET
- ;---------------------------------------------------------------
- Q_NO_ST: ;Q PARITY CHECK START ADDRESS
- MOV SI,W_DATA_AD_OFF ;SI=INITIAL START ADDRESS
- MOV CX,Q_NO ;LOOP KAISU = Q_NO
- OR CL,CL ;CL= 0 ?
- JZ Q_NO_ST_2 ;IF CL=0 SI= Q PARITY START ADDRESS
- Q_NO_ST_1: ADD SI,43*2 ;SI<- SI+43*2
- LOOP Q_NO_ST_1 ;
- Q_NO_ST_2: MOV AH,[SI] ;AH=START DATA
- RET
- ;-------------------------------------------------------------------
- T_SARCH: ;T MATRIX NO SARCH
- MOV DI,OFFSET T_MAT_TBL ;
- XOR BH,BH ;BH=0
- MOV BL,S0
- MOV CL,[DI+BX] ;CL <- S0 T_MATRIX_NO
- MOV BL,S1
- SUB CL,[DI+BX] ;CL<- S0 T_MATRIX_NO - S1 T_MATRIX_NO
- JBE RET_4
- INC CL ;IF CL>0 CL <- CL+1
- RET_4: ;POP ES ;RESTORE ES
- RET
- ;
- T_MAT_TBL DB (256+8) DUP (?)
- ;----------------------------------------------------------------------
- ;----------------------------------------------------------------------
- ROPRO ENDP
- E_O_P:
- ECC ENDP
- _TEXT ENDS
- END
-